-- -- Copyright 2014 Alessandro Gerlinger Romero -- -- This file is part of Hybrid fUML. -- -- Hybrid fUML is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- Hybrid fUML is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with Hybrid fUML. If not, see . -- ------------------------------------------------------------------------------------------------------------------------------------------------------------ -- APPROACH -- it is not focus to define a parser for expressions -- so each expression must be coded here using functions to read an write a value -- -- IT IS NOT THE SELECTED HARD PART, what does not mean that is easy ------------------------------------------------------------------------------------------------------------------------------------------------------------ -- EVALUATE function_fUML_evaluateBooleanExpression:: FUML_Semantics_Classes_Kernel_Value -> String -> Bool function_fUML_evaluateBooleanExpression v s | s == "mass > 0" = valM > 0.0 | s == "massCart > 0 and massRod > 0 and lengthRod > 0" = (valMC > 0.0 && valMR > 0.0 && valLR > 0.0) | s == "mass.position <= 0 and mass.velocity < 0" = if vMassRR /= FUML_Semantics_Classes_Kernel_ValueEmpty && vMassVR /= FUML_Semantics_Classes_Kernel_ValueEmpty && vMassPR /= FUML_Semantics_Classes_Kernel_ValueEmpty then (vPosR <= 0.0 && vVelR < 0.0) else False | s == "0 <= mass.velocity and mass.velocity <= 0.01 and 0.01 <= mass.position and not closeToTop" = if vMassRR /= FUML_Semantics_Classes_Kernel_ValueEmpty && vMassVR /= FUML_Semantics_Classes_Kernel_ValueEmpty && vMassPR /= FUML_Semantics_Classes_Kernel_ValueEmpty then (0.0 <= vVelR && vVelR <= 0.01 && 0.01 <= vPosR && not vCloseTopV) else False | s == "not (0 <= mass.velocity and mass.velocity <= 0.01 and 0.01 <= mass.position) and closeToTop" = if vMassRR /= FUML_Semantics_Classes_Kernel_ValueEmpty && vMassVR /= FUML_Semantics_Classes_Kernel_ValueEmpty && vMassPR /= FUML_Semantics_Classes_Kernel_ValueEmpty then not (0.0 <= vVelR && vVelR <= 0.01 && 0.01 <= vPosR) && vCloseTopV else False | s == "true" = True | s == "t >= 0" = True | otherwise = False where -- -- spring mass damper -- for expression "mass > 0" vMass = function_fUML_readStructuralFeatureAsStr v "mass" valM = if vMass /= FUML_Semantics_Classes_Kernel_ValueEmpty then function_Value_RealValue_value vMass else 0.0 -- -- pendulum -- for expression "massCart > 0 and massRod > 0 and lengthRod > 0" vMassC = function_fUML_readStructuralFeatureAsStr v "massCart" valMC = if vMassC /= FUML_Semantics_Classes_Kernel_ValueEmpty then function_Value_RealValue_value vMassC else 0.0 vMassR = function_fUML_readStructuralFeatureAsStr v "massRod" valMR = if vMassR /= FUML_Semantics_Classes_Kernel_ValueEmpty then function_Value_RealValue_value vMassR else 0.0 vLenR = function_fUML_readStructuralFeatureAsStr v "lengthRod" valLR = if vLenR /= FUML_Semantics_Classes_Kernel_ValueEmpty then function_Value_RealValue_value vLenR else 0.0 -- -- bouncing ball -- for expression "mass.position <= 0 and mass.velocity < 0" vMassRR = function_fUML_readStructuralFeatureAsStr v "mass" vMassRRO = function_Value_Reference_referent vMassRR vMassVR = function_fUML_readStructuralFeatureAsStr vMassRRO "velocity" vVelR = if vMassVR /= FUML_Semantics_Classes_Kernel_ValueEmpty then function_Value_RealValue_value vMassVR else 0.0 vMassPR = function_fUML_readStructuralFeatureAsStr vMassRRO "position" vPosR = if vMassPR /= FUML_Semantics_Classes_Kernel_ValueEmpty then function_Value_RealValue_value vMassPR else 0.0 vCloseTop = function_fUML_readStructuralFeatureAsStr v "closeToTop" vCloseTopV = if vCloseTop /= FUML_Semantics_Classes_Kernel_ValueEmpty then function_Value_BooleanValue_value vCloseTop else False ------------------------------------------------------------------------------------------------------------------------------------------------------------ -- COMPUTE rule_fUML_computeEquation:: FUML_Semantics_Classes_Kernel_Value -> String -> Rule() rule_fUML_computeEquation v s -- spring mass damper | s == "der(position) = velocity;mass*der(velocity) = force - springConstant * position - dampingCoefficient * velocity;" = do if vsFPos /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= nvsPos rule_fUML_addStructuralFeatureString v "position" nv else skip if vsFVel /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= nvsVel rule_fUML_addStructuralFeatureString v "velocity" nv else skip if length(function_fUML_hybridTrace v) > 0 && last(function_fUML_hybridTrace v) == ll then function_fUML_hybridTrace(v) := function_fUML_hybridTrace(v) ++ [cl] else function_fUML_hybridTrace(v) := function_fUML_hybridTrace(v) ++ [ll] ++ [cl] -- pendulum | s == "der(position) = velocity;der(angle) = angularVelocity;massCart * lengthRod * der(angularVelocity) = (massCart + massRod) * 9,81 * angle - force;massCart * der(velocity) = force - massRod * 9,81 * angle;" = do if vsFPosP /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= nvsPosP rule_fUML_addStructuralFeatureString v "position" nv else skip if vsFVelP /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= nvsVelP rule_fUML_addStructuralFeatureString v "velocity" nv else skip if vsFA /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= nvsPosPA rule_fUML_addStructuralFeatureString v "angle" nv else skip if vsFAV /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= nvsVelPA rule_fUML_addStructuralFeatureString v "angularVelocity" nv else skip if length(function_fUML_hybridTrace v) > 0 && last(function_fUML_hybridTrace v) == llP then function_fUML_hybridTrace(v) := function_fUML_hybridTrace(v) ++ [clP] else function_fUML_hybridTrace(v) := function_fUML_hybridTrace(v) ++ [llP] ++ [clP] -- boucingball reviewed -- ignore all the equation and get one to do the calculation following a manual causal analysis | s == "der(velocity) = acceleration;der(position) = velocity;mass * acceleration = flange_a.force;flange_a.position = position;" = do if bvsFPos /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= bnvsPos rule_fUML_addStructuralFeatureString bvsFMassO "position" nv else skip if bvsFVel /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= bnvsVel rule_fUML_addStructuralFeatureString bvsFMassO "velocity" nv else skip if bvsFAcc /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= bvsa rule_fUML_addStructuralFeatureString bvsFMassO "acceleration" nv else skip if length(function_fUML_hybridTrace v) > 0 && last(function_fUML_hybridTrace v) == llBB then function_fUML_hybridTrace(v) := function_fUML_hybridTrace(v) ++ [clBB] else function_fUML_hybridTrace(v) := function_fUML_hybridTrace(v) ++ [llBB] ++ [clBB] -- sysml | s == "der(t) = 1;" = do if tF /= FUML_Semantics_Classes_Kernel_ValueEmpty then do -- creating new value nv <- (rule_FUML_Semantics_Classes_Kernel_Value_create FUML_Semantics_Classes_Kernel_RealValue) function_Value_PrimitiveValue_type(nv) := real function_Value_RealValue_value(nv):= nt rule_fUML_addStructuralFeatureString tTO "t" nv else skip if length(function_fUML_hybridTrace v) > 0 && last(function_fUML_hybridTrace v) == llBBt then function_fUML_hybridTrace(v) := function_fUML_hybridTrace(v) ++ [clBBt] else function_fUML_hybridTrace(v) := function_fUML_hybridTrace(v) ++ [llBBt] ++ [clBBt] -- | otherwise = skip where -- -- SPRING MASS DAMPER -- -- reading current attributes vsFMass = function_fUML_readStructuralFeatureAsStr v "mass" vsMas = function_Value_RealValue_value vsFMass vsFPos = function_fUML_readStructuralFeatureAsStr v "position" vsPos = function_Value_RealValue_value vsFPos vsFVel = function_fUML_readStructuralFeatureAsStr v "velocity" vsVel = function_Value_RealValue_value vsFVel vsFK = function_fUML_readStructuralFeatureAsStr v "springConstant" vsK = function_Value_RealValue_value vsFK vsFb = function_fUML_readStructuralFeatureAsStr v "dampingCoefficient" vsb = function_Value_RealValue_value vsFb vsFf = function_fUML_readStructuralFeatureAsStr v "force" vsf = function_Value_RealValue_value vsFf -- acceleration = - position * springConstant - velocity * dampingCoefficient + force vsa = -vsPos * (vsK/vsMas) - vsVel * (vsb/vsMas) + (vsf/vsMas) -- new values nvsVel = (stsi* vsa) + vsVel --nvsPos = (stsi* nvsVel) + vsPos nvsPos = (stsi* vsVel) + vsPos -- last line ll = show (rt) ++ "," ++ show (pt) ++ "," ++ show lt ++ "," ++ show vsPos ++ "," ++ show vsVel ++ "," ++ show vsf ++ "," ++ show v -- current line cl = show (rt) ++ "," ++ show (pt+stsi) ++ "," ++ show lt ++ "," ++ show nvsPos ++ "," ++ show nvsVel ++ "," ++ show vsf ++ "," ++ show v -- -- PENDULUM -- -- reading current attributes vsFMassC = function_fUML_readStructuralFeatureAsStr v "massCart" vsMasC = function_Value_RealValue_value vsFMassC vsFMassR = function_fUML_readStructuralFeatureAsStr v "massRod" vsMasR = function_Value_RealValue_value vsFMassR vsFLenR = function_fUML_readStructuralFeatureAsStr v "lengthRod" vsLenR = function_Value_RealValue_value vsFLenR vsFPosP = function_fUML_readStructuralFeatureAsStr v "position" vsPosP = function_Value_RealValue_value vsFPosP vsFVelP = function_fUML_readStructuralFeatureAsStr v "velocity" vsVelP = function_Value_RealValue_value vsFVelP vsFA = function_fUML_readStructuralFeatureAsStr v "angle" vsA = function_Value_RealValue_value vsFA vsFAV = function_fUML_readStructuralFeatureAsStr v "angularVelocity" vsAV = function_Value_RealValue_value vsFAV vsFfP = function_fUML_readStructuralFeatureAsStr v "force" vsfP = function_Value_RealValue_value vsFfP g = 9.81 -- massCart * der(velocity) = force - massRod * 9,81 * angle; vsaVP = (vsfP - (vsMasR * g * vsA)) / vsMasC -- massCart * lengthRod * der(angularVelocity) = (massCart + massRod) * 9,81 * angle - force vsaAVP = ((vsMasC + vsMasR ) * g * vsA - vsfP ) / (vsMasC * vsLenR) -- new values nvsVelP = (stsi* vsaVP) + vsVelP --nvsPosP = (stsi* nvsVelP) + vsPosP nvsPosP = (stsi* vsVelP) + vsPosP nvsVelPA = (stsi* vsaAVP) + vsAV --nvsPosPA = (stsi* nvsVelPA) + vsA nvsPosPA = (stsi* vsAV) + vsA -- last line llP = show (rt) ++ "," ++ show (pt) ++ "," ++ show lt ++ "," ++ show vsPosP ++ "," ++ show vsVelP ++ "," ++ show vsA ++ "," ++ show vsAV ++ "," ++ show vsfP ++ "," ++ show v -- current line clP = show (rt) ++ "," ++ show (pt+stsi) ++ "," ++ show lt ++ "," ++ show nvsPosP ++ "," ++ show nvsVelP ++ "," ++ show nvsPosPA ++ "," ++ show nvsVelPA ++ "," ++ show vsfP ++ "," ++ show v -- -- BOUNCINGBALL REVIEWED -- -- reading current attributes bvsFMass = function_fUML_readStructuralFeatureAsStr v "mass" bvsFMassO = function_Value_Reference_referent bvsFMass bvsFg = function_fUML_readStructuralFeatureAsStr v "gravitionalAcceleration" bvsg = function_Value_RealValue_value bvsFg bvsFc = function_fUML_readStructuralFeatureAsStr v "controlForceValue" bvsc = function_Value_RealValue_value bvsFc -- from mass bvsFPos = function_fUML_readStructuralFeatureAsStr bvsFMassO "position" bvsPos = function_Value_RealValue_value bvsFPos bvsFVel = function_fUML_readStructuralFeatureAsStr bvsFMassO "velocity" bvsVel = function_Value_RealValue_value bvsFVel bvsFAcc = function_fUML_readStructuralFeatureAsStr bvsFMassO "acceleration" bvsAcc = function_Value_RealValue_value bvsFAcc bvsFMassV = function_fUML_readStructuralFeatureAsStr bvsFMassO "mass" bvsMass = function_Value_RealValue_value bvsFMassV -- new values -- acceleration bvsa = ( bvsc + bvsg ) / bvsMass -- new values bnvsVel = (stsi* bvsa) + bvsVel bnvsPos = (stsi* bvsVel) + bvsPos -- last line llBB = show (rt) ++ "," ++ show (pt) ++ "," ++ show lt ++ "," ++ show bvsPos ++ "," ++ show bvsVel ++ "," ++ show bvsAcc ++ "," ++ show bvsg ++ "," ++ show bvsc ++ "," ++ show v -- current line clBB = show (rt) ++ "," ++ show (pt+stsi) ++ "," ++ show lt ++ "," ++ show bnvsPos ++ "," ++ show bnvsVel ++ "," ++ show bvsa ++ "," ++ show bvsg ++ "," ++ show bvsc ++ "," ++ show v -- -- SYSML -- -- reading current attributes tTF = function_fUML_readStructuralFeatureAsStr v "timepiececonstraint" tTO = function_Value_Reference_referent tTF tF = function_fUML_readStructuralFeatureAsStr tTO "t" t = function_Value_RealValue_value tF nt = stsi+t -- last line llBBt = show (rt) ++ "," ++ show (pt) ++ "," ++ show lt ++ "," ++ show t ++ "," ++ show v -- current line clBBt = show (rt) ++ "," ++ show (pt+stsi) ++ "," ++ show lt ++ "," ++ show nt ++ "," ++ show v -- clock data -- locus l = function_fUML_locus -- rc = function_Locus_reactionClock l rt = function_fUML_Clock_currentTimeInt rc lc = function_Locus_logicalClock l lt = function_fUML_Clock_currentTimeInt lc pc = function_Locus_physicalClock l pt = function_Clock_currentTime pc stsi = function_Clock_resolution pc ------------------------------------------------------------------------------------------------------------------------------------------------------------ -- HELP -- generate a trace here with a dynamic function to plot a graph -- clocks state a, v, p function_fUML_hybridTrace:: Dynamic( FUML_Semantics_Classes_Kernel_Value -> [String]) function_fUML_hybridTrace = initAssocs "function_fUML_hybridTrace" [] instance AsmTerm [String] where asmDefault = []